/**
*	@file ResultTable.h
*
*	@brief this header file is defining table structure
*
*	@author li yuchen
*
*	@date 1/28/2011
*/
#ifndef RESULTTABLE_H
#define RESULTTABLE_H

#include <vector>
#include <string>
#include "QueryVarTable.h"
using namespace std;


/** @brief ResultTable assume a table cannot have same query_var_idx as different columns */
class ResultTable{
public:
	/** @brief must specify the columns (query variable indexes) */
	ResultTable(vector<int> query_var_indexes);

	ResultTable(QueryVarIdx single_query_var,bool enum_var = false);
	ResultTable(QueryVarIdx query_arg_a,QueryVarIdx query_arg_b);

	~ResultTable();

	/** @return a vector which contains the query var idxes of this query result (column name) */
	inline vector<int>* get_query_var_idxes(){return &this->query_var_idxes_;};

	/**
	*	@brief rows represent each tuple result
	*	@return the whole table data
	*/
	inline vector<vector<int>>* get_table_data(){return &this->table_data_;};

	/**
	*	@brief insert a new query tuple into the table
	*		size must be size as query_var_idxes
	*/
	void AddResultTuple(vector<int>& tuple);

	/**
	*	@return three vectors which 
	*		comm_idx_a contains the column idxes in the this table
	*		comm_idx_b contains the column idxes in the table_b
	*		they have the same size and their corresponding column has the same query var idxes
	*		diff_cols_b which is the column idxes which appears in table_b but not appears in this table
	*/
	void FindCommAttri(ResultTable* table_b,vector<int>& comm_cols_a,vector<int>& comm_cols_b,vector<int>& diff_cols_b);

	/**
	*	@return a result table which contains the projection on the table give the columns
	*		the change made to this table is that the cols projected is sorted
	*		cols means the column indexes not the query var idxes
	*/	
	ResultTable* ProjectOnCols(vector<int>& cols, bool need_sort);

	/**
	*	@brief implemented using left outer join
	*	@return a result which is the join of these two table
	*/
	ResultTable* NaiveJoinResultTable(ResultTable* table_b);

	/**
	*	@brief assume this and table_b have already sorted with given idxes comm_cols_a and com_cols_b
	*		where diff_cols represent the cols of table_b which do not appear in table a
	*/
	ResultTable* SortMergeJoin(ResultTable* table_b,vector<int>& comm_cols_a,vector<int>& comon_cols_b, vector<int>& diff_cols_b);
	
	/** @brief assume both result table do not have common columns */
	ResultTable* CartesianProduct(ResultTable* table_b,bool left_outer_join);

	/**	@return true if it is prefix matched with the sorted_idxes_ */
	bool IsColumnSorted(vector<int> cols_check);

	/** @return the sorted columns of the given table */
	vector<int>* get_sorted_idxes(){ return &sorted_idxes_;};

	string ToString();
	/** @brief sort the table based on the given column idxes (not the query variable idxes) */
	void SortResultTable(vector<int>& index_to_sort);

	
private:
	vector<int> query_var_idxes_;
	vector<vector<int>> table_data_;
	vector<int> sorted_idxes_;
	void set_sorted_idxes(vector<int>& sorted_idxes){ this->sorted_idxes_ = sorted_idxes;};
	
};

#endif